﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Microsoft.ApplicationBlocks.Data;

namespace ObelixTI
{
    public class Seguridad
    {
        #region "Variables privadas"
        private int _idUsuario;
        private string _usuario;
        private string _clave;
        private string _nombre;
        private string _correo;
        private bool _autenticado;
        private string _conn;

        public enum Permisos
        {
            Consultar = 1,
            Agregar,
            Editar,
            Eliminar,
            Especial
        }

        public enum Accion
        {
            Insertar = 1,
            Eliminar
        }

        #endregion

        #region "Propiedades"

        /// <summary>
        /// Guarda el id del usuario. De solo lectura
        /// </summary>
        public int IdUsuario
        {
            get { return this._idUsuario; }
        }

        /// <summary>
        /// Guarda el nombre completo del usuario (nombres y apellidos)
        /// </summary>
        public string Nombre
        {
            get { return this._nombre; }
            set { this._nombre = value; }
        }

        /// <summary>
        /// Guarda el nombre de usuario (login)
        /// </summary>
        public string Usuario
        {
            get { return this._usuario; }
        }


        /// <summary>
        /// Guarda el correo del usuario
        /// </summary>
        public string Correo
        {
            get { return this._correo; }
            set { this._correo = value; }
        }

        /// <summary>
        /// True si el usuario tiene permisos sobre la aplicación
        /// </summary>
        public bool Autenticado
        {
            get { return this._autenticado; }
        }

        #endregion

        #region "Constructores"

        public Seguridad(string sqlConnect)
        {
            this._conn = sqlConnect;
        }

        #endregion

        #region "Métodos públicos get"

        /// <summary>
        /// Retorna dataset con los roles activos
        /// </summary>
        /// <returns></returns>
        public DataSet GetRoles()
        {
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetRoles");
        }

        /// <summary>
        /// retorna arreglo con los ids de los roles a los que pertenece el usuario que le llega
        /// </summary>
        /// <param name="idUsuario"></param>
        /// <returns></returns>
        public int[] GetRolesUsuario(int idUsuario)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdUsuario", idUsuario);
            DataSet ds = SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetRolesUsuario", param);

            int[] arrRoles = new int[ds.Tables[0].Rows.Count];
            for (int i = 0; i < arrRoles.Length; i++)
            {
                arrRoles[i] = Convert.ToInt32(ds.Tables[0].Rows[i][0].ToString());
            }

            return arrRoles;
        }



        /// <summary>
        /// Retorna los menus sobre los cuales el rol tiene y no tiene permiso
        /// </summary>
        /// <param name="IdAplicacion"></param> 
        /// <param name="IdRol"></param> 
        /// <returns></returns>
        public DataSet GetPermisosRol(int IdAplicacion, int IdRol)
        {

            SqlParameter[] param = new SqlParameter[2];
            param[0] = new SqlParameter("@IdAplicacion", IdAplicacion);
            param[1] = new SqlParameter("@IdRol", IdRol);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetPermisosRol", param);
        }




        /// <summary>
        /// Retorna toda la información básica del usuario
        /// </summary>
        /// <returns></returns>
        public DataSet GetUsuarioById(int idUsuario)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdUsuario", idUsuario);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetUsuarioById", param);
        }

        /// <summary>
        /// Retorna array con los permisos que se tienen sobre el menú que le llega. Los permisos se retornan
        /// en este orden: consultar, agregar, editar, eliminar, especial1, especial2
        /// </summary>
        /// <param name="idMenu"></param>
        /// <returns></returns>
        public Array GetPermisosMenu(int idMenu)
        {
            Array arrRetorno = null;
            return arrRetorno;
        }

        /// <summary>
        /// Retorna información de las páginas sobre las que el usuario tiene permisos en la aplicación que 
        /// le llega. Se diferencia de GetMenuUsuario(int idAplicacion, int idUsuario) en que esta retorna
        /// el menú del usuario logueado
        /// </summary>
        /// <param name="idAplicacion"></param>
        /// <returns></returns>
        public DataSet GetMenu(int idAplicacion)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdAplicacion", idAplicacion);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetMenu", param);
        }


        /// <summary>
        /// </summary>
        /// <param name="idAplicacion"></param>
        /// <returns></returns>
        public DataSet GetMenusPadres(int idAplicacion)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdAplicacion", idAplicacion);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetMenusPadres", param);
        }


        /// <summary>
        /// Retorna información de las páginas sobre las que el perfil que le llega tiene permisos en
        /// la aplicación que le llega. 
        /// </summary>
        /// <param name="idAplicacion"></param>
        /// <param name="idPerfil"></param>
        /// <returns></returns>
        public DataSet GetMenuRol(int idAplicacion, int idRol)
        {
            SqlParameter[] param = new SqlParameter[2];
            param[0] = new SqlParameter("@IdAplicacion", idAplicacion);
            param[1] = new SqlParameter("@IdRol", idRol);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetMenuRol", param);
        }

        /// <summary>
        /// Retorna información de las páginas sobre las que el usuario que le llega tiene permisos en
        /// la aplicación que le llega. Se diferencia de GetMenu(int idAplicacion) en que esta retorna la información 
        /// de cualquier usuario, no necesariamente el que está logueado
        /// </summary>
        /// <param name="idAplicacion"></param>
        /// <param name="idUsuario"></param>
        /// <returns></returns>
        public DataSet GetMenuUsuario(int idAplicacion, int idUsuario)
        {
            SqlParameter[] param = new SqlParameter[2];
            param[0] = new SqlParameter("@IdAplicacion", idAplicacion);
            param[1] = new SqlParameter("@IdUsuario", idUsuario);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetMenuUsuario", param);
        }

        /// <summary>
        /// Retorna listado de todos los usuarios activos
        /// </summary>        
        /// <returns></returns>
        public DataSet GetUsuarios()
        {
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetUsuarios");
        }



        /// <summary>
        /// Retorna listado de todos los usuarios activos
        /// </summary>   
        /// <param name="NOMBRE1"></param> 
        /// <param name="NOMBRE2"></param>
        /// <param name="APELLIDO1"></param> 
        /// <param name="APELLIDO2"></param> 
        /// <param name="CEDULA"></param>
        /// <param name="USUARIO"></param> 
        /// <returns></returns>
        public DataSet GetUsuariosFilter(string NOMBRE1, string NOMBRE2, string APELLIDO1, string APELLIDO2, string USUARIO, string CEDULA)
        {
            SqlParameter[] param = new SqlParameter[6];
            param[0] = new SqlParameter("@NOMBRE1", NOMBRE1);
            param[1] = new SqlParameter("@NOMBRE2", NOMBRE2);
            param[2] = new SqlParameter("@APELLIDO1", APELLIDO1);
            param[3] = new SqlParameter("@APELLIDO2", APELLIDO2);
            param[4] = new SqlParameter("@USUARIO", USUARIO);
            param[5] = new SqlParameter("@CEDULA ", CEDULA);

            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetUsuariosFilter", param);
        }



        /// <summary>
        /// Retorna listado de usuario con permisos sobre la aplicacion que le llega
        /// </summary>
        /// <param name="idAplicacion"></param>
        /// <returns></returns>
        public DataSet GetUsuariosAplicacion(int idAplicacion)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdAplicacion", idAplicacion);
            return SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "GetUsuariosAplicacion", param);
        }

        /// <summary>
        /// Retorna listado de aplicaciones activas
        /// </summary>
        /// <returns></returns>
        public DataSet GetAplicaciones()
        {
            DataSet ds = new DataSet();
            return ds;
        }

        #endregion

        #region "Métodos públicos de actualizar"

        /// <summary>
        /// Actualiza (crea o actualizar) el rol que le llega
        /// </summary>
        /// <param name="id">0 si se va a insertar un registro. De los contrario, es el id del registro a actualizar</param>
        /// <param name="nombre"></param>
        /// <param name="descripcion"></param>
        public void ActualizarRol(int id, string nombre, string descripcion)
        {
            SqlParameter[] param = new SqlParameter[3];
            param[0] = new SqlParameter("@Id", id);
            param[1] = new SqlParameter("@Nombre", nombre);
            param[2] = new SqlParameter("@Descripcion", descripcion);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "ActualizarRol", param);
        }


        /// <summary>
        /// Actualiza (crea o actualizar) el menu que le llega
        /// </summary>
        /// <param name="id">0 si se va a insertar un registro. De los contrario, es el id del registro a actualizar</param>
        /// <param name="idPadre"></param> 
        /// <param name="nombre"></param>
        /// <param name="descripcion"></param>
        /// <param name="url"></param> 
        public void ActualizarMenu(int id, int idPadre, string nombre, string descripcion, string url)
        {
            SqlParameter[] param = new SqlParameter[5];
            param[0] = new SqlParameter("@Id", id);
            param[1] = new SqlParameter("@idPadre", idPadre);
            param[2] = new SqlParameter("@nombre", nombre);
            param[3] = new SqlParameter("@descripcion", descripcion);
            param[4] = new SqlParameter("@url", url);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "ActualizarMenu", param);
        }

        /// <summary>
        /// Actualiza el usuario que le llega. Retorna el id del usuario
        /// </summary>
        /// <param name="id">Si id=0 se isnerta el usuario, de lo contrario se actualiza</param>
        /// <param name="idCargo"></param>
        /// <param name="idArea"></param>
        /// <param name="usuario"></param>
        /// <param name="clave">Solamente se utiliza cuando se va a insertar</param>
        /// <param name="cedula"></param>
        /// <param name="nombre1"></param>
        /// <param name="nombre2"></param>
        /// <param name="apellido1"></param>
        /// <param name="apellido2"></param>
        /// <param name="telefono"></param>
        /// <param name="correo"></param>
        /// <param name="foto"></param>
        public int ActualizarUsuario(int id, int idCargo, int idArea, string usuario, string clave, string cedula
            , string nombre1, string nombre2, string apellido1, string apellido2, string telefono, string correo, string foto, int IdRol)
        {
            SqlParameter[] param = new SqlParameter[14];
            param[0] = new SqlParameter("@Id", id);
            param[1] = new SqlParameter("@IdCargo", idCargo);
            param[2] = new SqlParameter("@IdArea", idArea);
            param[3] = new SqlParameter("@Usuario", usuario);
            param[4] = new SqlParameter("@Clave", clave);
            param[5] = new SqlParameter("@Cedula", cedula);
            param[6] = new SqlParameter("@Nombre1", nombre1);
            param[7] = new SqlParameter("@Nombre2", nombre2);
            param[8] = new SqlParameter("@Apellido1", apellido1);
            param[9] = new SqlParameter("@Apellido2", apellido2);
            param[10] = new SqlParameter("@Telefono", telefono);
            param[11] = new SqlParameter("@Correo", correo);
            param[12] = new SqlParameter("@Foto", foto);
            param[13] = new SqlParameter("@IdRol", IdRol);
            param[0].Direction = ParameterDirection.InputOutput;
            DataSet ds;

            ds = SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "ActualizarUsuario", param);

            int resultado;
            resultado = 0;
            if (ds.Tables[0].Rows.Count > 0)
            {
                if (id == 0)
                {
                    resultado = Convert.ToInt16(ds.Tables[0].Rows[0]["ID"].ToString()); 
                }            
            
            }
                     
            return resultado;
        }

        /// <summary>
        /// Actualiza el detalle del permiso que le llega (Actualiza el agregar, editar, eliminar, etc del permiso)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="agregar"></param>
        /// <param name="editar"></param>
        /// <param name="eliminar"></param>
        /// <param name="consultar"></param>
        /// <param name="especial1"></param>
        /// <param name="especial2"></param>
        public void ActualizarPermiso(int id, bool agregar, bool editar, bool eliminar, bool consultar, bool especial1, bool especial2)
        {
            SqlParameter[] param = new SqlParameter[7];
            param[0] = new SqlParameter("@Id", id);
            param[1] = new SqlParameter("@Agregar", agregar);
            param[2] = new SqlParameter("@Editar", editar);
            param[3] = new SqlParameter("@Eliminar", eliminar);
            param[4] = new SqlParameter("@Consultar", consultar);
            param[5] = new SqlParameter("@Especial1", especial1);
            param[6] = new SqlParameter("@Especial2", especial2);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "ActualizarPermiso", param);
        }




        /// <summary>
        /// Actualiza (crea y elimina) los roles a los que pertenece el usuario que le llega
        /// </summary>
        /// <param name="idUsuario"></param>
        /// <param name="roles"></param>
        public void ActualizarUsuarioRol(int idUsuario, int[] roles)
        {
            //Construye string con los ids de los roles
            string strRoles = "";
            for (int i= 0; i< roles.Length; i++)
            {
                strRoles += roles[i].ToString() + ",";
            }

            SqlParameter[] param = new SqlParameter[2];
            param[0] = new SqlParameter("@IdUsuario", idUsuario);
            param[1] = new SqlParameter("@Roles", strRoles);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "ActualizarUsuarioRol", param);

        }

        /// <summary>
        /// Actualiza (crea y elimina) las sucursales a los que pertenece el usuario que le llega
        /// </summary>
        /// <param name="idUsuario"></param>
        /// <param name="roles"></param>
        public void ActualizarUsuarioSucursal(int idUsuario, int[] sucursales)
        {
            //Construye string con los ids de los roles
            string strSucursales = "";
            for (int i = 0; i < sucursales.Length; i++)
            {
                strSucursales += sucursales[i].ToString() + ",";
            }

            SqlParameter[] param = new SqlParameter[2];
            param[0] = new SqlParameter("@IdUsuario", idUsuario);
            param[1] = new SqlParameter("@Sucursales", strSucursales);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "ActualizarUsuarioSucursal", param);
        }

        /// <summary>
        /// Actualiza (crea y elimina) el permiso del rol
        /// </summary>
        /// <param name="idPerfil"></param>
        /// <param name="idMenu"></param>
        public void ActualizarPermisoRol(int idRol, int idMenu, Accion accion)
        {
            SqlParameter[] param = new SqlParameter[3];
            param[0] = new SqlParameter("@IdRol", idRol);
            param[1] = new SqlParameter("@IdMenu", idMenu);
            if (accion == Accion.Eliminar)
                param[2] = new SqlParameter("@Accion", "1");
            else if (accion == Accion.Insertar)
                param[2] = new SqlParameter("@Accion", "0");
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "ActualizarPermisoRol", param);

        }

        #endregion

        #region "Métodos públicos de eliminar"

        /// <summary>
        /// Inactiva el registro que le llega
        /// </summary>
        /// <param name="id"></param>
        public void EliminarAplicacion(int id)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@Id", id);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "EliminarAplicacion", param);
        }

        /// <summary>
        /// Inactiva el registro que le llega
        /// </summary>
        /// <param name="id"></param>
        public  string EliminarRol(int id)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdRol", id);


            string retorno = "";    

            DataSet ds = SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "EliminarRol", param);

            if (ds.Tables[0].Rows.Count > 0)
            {
                retorno = ds.Tables[0].Rows[0]["RESULTADO"].ToString();
            }
            return retorno; 
        }

        /// <summary>
        /// Inactiva el registro que le llega
        /// </summary>
        /// <param name="id"></param>
        public void EliminarUsuario(int id)
        {
            SqlParameter[] param = new SqlParameter[1];
            param[0] = new SqlParameter("@IdUsuario", id);
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "EliminarUsuario", param);
        }

        #endregion

        #region "Otros Métodos públicos"

        /// <summary>
        /// Retorna vacío si el usuario tiene permisos sobre la aplicación que le llega, de lo contrario
        /// retorna un mensaje indicando la causa de porqué no ha sido autenticado
        /// </summary>
        /// <param name="idAplicacion"></param>
        /// <returns></returns>
        public string Autenticar(int idAplicacion, string usuario, string clave)
        {
            SqlParameter[] param = new SqlParameter[3];
            param[0] = new SqlParameter("@IdAplicacion", idAplicacion);
            param[1] = new SqlParameter("@Usuario", usuario);
            param[2] = new SqlParameter("@Clave", clave);
            DataSet ds = SqlHelper.ExecuteDataset(this._conn, CommandType.StoredProcedure, "Autenticar", param);

            string retorno = "";
            if (ds.Tables[0].Rows.Count == 0)
                return "El usuario y clave digitados no existen";
            else
            {
                //El usuario y clave si existen, se verifica si tiene permisos sobre la aplicación
                if (ds.Tables[1].Rows.Count == 0)
                {
                    this._autenticado = false;
                    return "No tiene permisos para ingresar a la aplicación";
                }
                else
                {
                    this._autenticado = true;
                    this._idUsuario = Convert.ToInt32(ds.Tables[0].Rows[0]["ID"].ToString());
                    this._nombre = ds.Tables[0].Rows[0]["NOMBRE1"].ToString() + " " + ds.Tables[0].Rows[0]["APELLIDO1"].ToString();
                }
                
            }
           
            return retorno;
        }

        /// <summary>
        /// Modifica la contraseña del usuario
        /// </summary>
        /// <param name="antigua"></param>
        /// <param name="nueva"></param>
        /// <returns></returns>
        public string CambiarContrasena(string antigua, string nueva, int idUsuario)
        {
            SqlParameter[] param = new SqlParameter[4];
            param[0] = new SqlParameter("@IdUsuario", idUsuario);
            param[1] = new SqlParameter("@Antigua", antigua);
            param[2] = new SqlParameter("@Nueva", nueva);
            param[3] = new SqlParameter("@Mensaje", SqlDbType.VarChar, 500);
            param[3].Direction = ParameterDirection.Output;
            SqlHelper.ExecuteNonQuery(this._conn, CommandType.StoredProcedure, "CambiarContrasena", param);

            return param[3].Value.ToString();        
        }


        #endregion


        //public DataSet GetMenuUsuario(int idAplicacion)
        //{
        //    throw new NotImplementedException();
        //}
    }
}
